测量资源加载和部署的时间

Kanzi 中,通过资源剖析,您可以测量加载和部署资源和预设件到 Kanzi 应用程序中的时间。

Kanzi 中,资源是您可以在应用程序的不同部分重用的项。例如,网格数据 (Mesh Data) 资源定义一个模型 (Model) 节点的几何形状,且您可以在不同的节点中使用相同的颜色笔刷 (Color Brush) 笔刷来设置前景笔刷 (Foreground Brush)背景笔刷 (Background Brush) 属性。 预设件(预制模板)可用于构造应用程序并创建统一接口。您可以使用预设件创建应用程序的构建块,并简化应用程序的维护。

要使用资源剖析:

  1. 在应用程序配置中启用资源剖析。请参阅 启用资源剖析
  2. 在应用程序代码中实现资源剖析数据的记录,然后运行应用程序,以收集并记录资源剖析数据。请参阅记录资源剖析数据
  3. 要测量在您的 Kanzi 应用中资源加载和部署的性能,请分析资源剖析数据。请参阅分析资源剖析数据

启用资源剖析

要开始资源剖析,您必须启用资源剖析类别。

要在应用程序配置中启用资源剖析,在以下任一项中使用 ProfilingCategoryFilter 设置:

要启用或禁用应用程序期间的资源剖析,启用或禁用相应的剖析类别:

在您启用资源剖析后,您可以收集资源剖析数据并将数据写入文件中。请参阅记录资源剖析数据

记录资源剖析数据

要分析 Kanzi 应用程序中的资源加载和部署,记录该资源剖析数据。在记录资源剖析数据之前,您必须启用资源剖析。请参阅 启用资源剖析

在启用资源剖析后,Kanzi 剖析应用程序中各种资源的加载和部署,并存储资源剖析程序中的剖析数据。在您的应用程序代码中实现已收集剖析数据的记录。Kanzi 提供 ResourceProfilingPtreePopulator 类,您可以用来将资源剖析数据填入 Boost 属性。然后,您可以使用 Boost 中提供的 JSON 格式化程序以 JSON 格式记录剖析数据。

要记录资源剖析数据:

  1. 在您的应用程序代码中,包括记录资源剖析数据所需的头文件。
    //定义标准输入/输出流对象。
    #include <kanzi/core/cpp/iostream.hpp>
    //提供实现字符串流输入/输出操作的类。
    #include <kanzi/core/cpp/sstream.hpp>
    //提供用资源剖析数据填充 Boost 属性树的功能。
    #include <kanzi/core.ui/resource/resource_profiling_ptree_populator.hpp>
    //提供将 Boost 属性树变换为 JSON 并将其写入文件的功能。
    #include <boost/property_tree/json_parser.hpp>
  2. 向您的应用程序添加输出资源剖析数据的代码。
    例如,要在应用程序退出时Kanzi 调用的回调 onShutDown() 中记录剖析数据到 cout,添加此代码:
        void onShutdown() KZ_OVERRIDE
        {
            //用资源剖析数据填充 Boost 属性树。
            ptree resourceProfilingDataTree = ResourceProfilingPtreePopulator::populatePropertyTree(getResourceManager()->getResourceProfiler());
            //将属性树以 JSON 格式写入到字符串流中。
            stringstream ss;
            boost::property_tree::json_parser::write_json(ss, resourceProfilingDataTree);
            //Boost json_writer 将“/”视为转义字符,并在每个“/”之前添加“\”。
            //这将影响 kzb URL 显示的方式。
            //此代码输出 json 到 cout,用“/”替换“\/”。
            string str(ss.str());
            string_view strView(str);
            while (!strView.empty())
            {
                size_t backSlashPos = strView.find("\\/");
                if (backSlashPos == string_view::npos)
                {
                    cout << strView;
                    strView = string_view();
                    continue;
                }
                cout << strView.substr(0, backSlashPos);
                strView = strView.substr(backSlashPos + 1);
            }
            cout << "\n";
        }
  3. 使用其中一个 Profiling build 配置构建您的应用程序,并运行该应用程序。您可以在退出应用程序时在控制台窗口中查看剖析数据。
    要在 Windows 上构建并运行您的应用程序:
    1. 在 Visual Studio 中使用 GL_vs2015_Profiling 构建配置构建您的应用程序。
    2. 在 Windows 上运行 Kanzi Profiling build 时,没有控制台窗口。要记录资源剖析数据,打开您计算机上的命令行界面,然后运行应用程序,将应用程序输出重定向至要存储资源剖析信息的文件。
      Application\output\Win32\GL_vs2015_Profiling\My_application.exe > MyApplicationResourceProfiling.json

Kanzi 向输出文件写入资源剖析数据,其中包含:

...
{
    "ThreadContexts": {
        "Resource manager loader thread 1": [
            ...
        ]
        "Resource manager main thread": [
            { resource profiling context of resourceX },
            { resource profiling context of resourceY },
            ...
            { resource profiling context of resourceZ }
        ],
        "Resource manager loader thread 0": [
            ...
            { resource profiling context of resourceY },
            ...
        ],
        "Resource manager loader thread 2": [
            ...
            ...
            { resource profiling context of resourceZ },
            ...
        ]
    },
    "ResourceProfilingDataSamples": [
        ...
        { profiling data sample for resourceX },
        { profiling data sample for resourceY },
        { profiling data sample for resourceZ },
        ...
   ]
}
...

关于为滚动视图示例记录的资源剖析数据示例,请参阅分析资源剖析数据

分析资源剖析数据

在您启用资源剖析和收集数据后,分析资源剖析程序采集的数据。

资源剖析数据包括:

例如,收集和分析滚动视图示例应用程序的资源剖析数据。

资源剖析数据包括如下信息:

资源获取

通常在应用程序启动时,Kanzi 获取 StartupPrefab 预设件模板,并将其实例化为屏幕 (Screen) 节点。要优化加载资源的性能,在获取启动预设件后,Kanzi 迭代屏幕 (Screen) 节点的子孙节点,并收集这些节点使用的所有资源的 URL。Kanzi 然后异步获取这些资源。
例如,在滚动视图示例应用程序中,City 节点使用City 网格。因为City 节点是屏幕 (Screen) 节点的其中一个子孙节点,Kanzi 异步获取City 网格。

在为滚动视图示例应用程序采集的资源剖析数据中,您可以在 Resource manager main thread 资源剖析上下文中找到City 网格的 ResourceAcquire 上下文。该上下文的 AcquireAsynchronously 特性被设置为 true,显示Kanzi 按预期异步获取了City 网格。

ResourceAcquire 上下文的父上下文是 AcquireResourcesAsynchronously 上下文,它是 MainLoop 上下文的依赖上下文。MainLoop 上下文的 MainLoopCounter 特性值为 "0",意味着 Kanzi 在第一个主循环迭代期间异步获取了City 网格。

AcquireResourcesAsynchronously 上下文具有依赖上下文,这些上下文与获取屏幕 (Screen) 节点的子孙节点使用的其他资源有关。

        “Resource manager main thread": [
            {
                "ContextID": “233269032",
                "ContextName": “MainLoop",
                "DependenciesDuration": “720909688",
                "MainLoopCounter": “0",
                "TimeStamp": “364",
                "DependencyContexts": [
                    {
                    ...
                    },
                    {
                        "ContextID": “200060624",
                        "ContextName": “AcquireResourcesAsynchronously",
                        "DependenciesDuration": “0",
                        "TimeStamp": “107493151",
                        "DependencyContexts": [
                            ...
                            {
                                "AcquireAsynchronously": “true",
                                "ContextID": “199287920",
                                "ContextName": “ResourceAcquire",
                                "DependenciesDuration": “0",
                                "ResourceUrl": “kzb://scroll_view/Mesh Data/City",
                                "TimeStamp": “107551499"
                            },
                            ...

资源加载 (Resource loading)

Kanzi 加载线程并行加载那些设置为异步加载的资源。对于每个异步加载的资源,Kanzi 创建一个加载任务,并将该任务放置在加载队列中,加载线程从中获取要执行的加载任务。当加载线程执行加载任务,资源剖析程序为该加载线程创建 ResourceLoading 上下文。

City 网格的 ResourceLoading 上下文是 "Resource manager loader thread 1" 线程的其中一个资源加载上下文。在 ResourceLoading 上下文中:

        “Resource manager loader thread 1": [
            ...
            {
                "ContextID": “234230448",
                "ContextName": “ResourceLoading",
                "DependenciesDuration": “0",
                "LoadedResourceID": “233255432",
                "LoadedResourceType": “Kanzi.Mesh",
                "LoadedResourceUrl": “kzb://scroll_view/Mesh Data/City",
                "ResourceLoadingDuration": “869380",
                "TimeStamp": “626864207"
            }
                ...

在加载线程完成 City 网格资源的加载后,它将该资源加载任务放到该资源管理器的完成队列中,待 Kanzi 主线程进一步处理。在加载线程将已完成任务放到该队列中以后,Kanzi 主线程处理完成队列。

资源部署

Kanzi 主线程处理 City 网格资源的加载任务时,资源剖析程序创建 FinishingQueue::processTask 上下文。在 FinishingQueue::processTask 上下文中,Description 特性显示加载任务的任务索引和完成队列中的任务数量。加载任务的处理包括资源部署,这是资源获取的最后阶段。ResourceDeployment 上下文是 FinishingQueue::processTask 上下文的依赖上下文。

        “Resource manager main thread": [
            {
                "ContextID": “233269032",
                "ContextName": “MainLoop",
                "DependenciesDuration": “720909688",
                "MainLoopCounter": “0",
                "TimeStamp": “364",
                "DependencyContexts": [
                        ...
                        ]
                    },
                    ...
                    {
                        "ContextID": “235741464",
                        "ContextName": “FinishingQueue::processTask",
                        "DependenciesDuration": “52920957",
                        "Description": “Task index 0, queue size 1",
                        "TimeStamp": “647529122",
                        "DependencyContexts": [
                            {
                                "ContextID": “234146616",
                                "ContextName": “ResourceDeployment",
                                "DependenciesDuration": “47990578",
                                "DeployedResourceID": “233255432",
                                "DeployedResourceType": “Kanzi.Mesh",
                                "DeployedResourceUrl": “kzb://scroll_view/Mesh Data/City",
                                "DeploymentDuration": “4930379",
                                "TimeStamp": “647530216",
                                "DependencyContexts": [
                                    ...

City 网格使用 3D 资产和多种材质。Kanzi 在部署 City 网格期间获取这些资源。City 网格依赖的这些资源的 ResourceAcquire 上下文被添加到City 网格的 ResourceDeployment 上下文中。
例如,在 City 网格的 ResourceDeployment 上下文依赖树中,您可以看到 City 网格使用 Park2 材质,这种材质又反过来使用冯氏 (Phong) 材质类型。在 City 网格的 ResourceDeployment 上下文中,DependenciesDuration 特性显示加载和部署City 网格依赖的资源的时间(以纳秒为单位)。

                                “ContextID": “234146616",
                                "ContextName": “ResourceDeployment",
                                "DependenciesDuration": “47990578",
                                "DeployedResourceID": “233255432",
                                "DeployedResourceType": “Kanzi.Mesh",
                                "DeployedResourceUrl": “kzb://scroll_view/Mesh Data/City",
                                "DeploymentDuration": “4930379",
                                "TimeStamp": “647530216",
                                "DependencyContexts": [
                                    {
                                        "AcquireAsynchronously": “false",
                                        "ContextID": “234125352",
                                        "ContextName": “ResourceAcquire",
                                        "DependenciesDuration": “14838173",
                                        "ResourceUrl": “kzb://scroll_view/Materials/Park2",
                                        "TimeStamp": “647530946",
                                        "DependencyContexts": [
                                            {
                                                "ContextID": “234145976",
                                                "ContextName": “ResourceLoading",
                                                "DependenciesDuration": “0",
                                                "LoadedResourceID": “235741752",
                                                "LoadedResourceType": “Kanzi.Material",
                                                "LoadedResourceUrl": “kzb://scroll_view/Materials/Park2",
                                                "ResourceLoadingDuration": “0",
                                                "TimeStamp": “647550638"
                                            },
                                            {
                                                "ContextID": “234147416",
                                                "ContextName": “ResourceDeployment",
                                                "DependenciesDuration": “14806082",
                                                "DeployedResourceID": “235741752",
                                                "DeployedResourceType": “Kanzi.Material",
                                                "DeployedResourceUrl": “kzb://scroll_view/Materials/Park2",
                                                "DeploymentDuration": “32091",
                                                "TimeStamp": “647552097",
                                                "DependencyContexts": [
                                                    {
                                                        "AcquireAsynchronously": “false",
                                                        "ContextID": “234126184",
                                                        "ContextName": “ResourceAcquire",
                                                        "DependenciesDuration": “14806082",
                                                        "ResourceUrl": “kzb://scroll_view/Material Types/Phong",
                                                        "TimeStamp": “647553191",
                                                        "DependencyContexts": [
                                                            {
                                                                "ContextID": “234146536",
                                                                "ContextName": “ResourceLoading",
                                                                "DependenciesDuration": “0",
                                                                "LoadedResourceID": “235740120",
                                                                "LoadedResourceType": “Kanzi.ShaderProgram",
                                                                "LoadedResourceUrl": “kzb://scroll_view/Material Types/Phong",
                                                                "ResourceLoadingDuration": “13129",
                                                                "TimeStamp": “647562672"
                                                            },
                                                            {
                                                                "ContextID": “234146376",
                                                                "ContextName": “ResourceDeployment",
                                                                "DependenciesDuration": “0",
                                                                "DeployedResourceID": “235740120",
                                                                "DeployedResourceType": “Kanzi.ShaderProgram",
                                                                "DeployedResourceUrl": “kzb://scroll_view/Material Types/Phong",
                                                                "DeploymentDuration": “14792953",
                                                                "TimeStamp": “647576530"
                                                            }
                                                        ]
                                                    }
                                                ]
                                            }
                                        ]
                                    },

另请参阅

资源剖析参考

测量应用程序性能

配置应用程序

资源

使用预设件